package com.kssoft.ebd.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.kssoft.ebd.common.NaXiAreaCode;
import com.kssoft.ebd.common.Broadcast;
import com.kssoft.ebd.common.XydBroadcastConfig;
import com.kssoft.ebd.dto.req.IssueLiveStreamParamDTO;
import com.kssoft.ebd.dto.rest.IssueLiveStreamDTO;
import com.kssoft.ebd.service.ApiBroadcastService;
import com.kssoft.ebd.service.XydBroadcastService;
import com.kssoft.ebd.spider.http.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author liwu
 * @since 2025/9/16
 */
@Service
public class XydBroadcastServiceImpl  implements XydBroadcastService {
    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(XydBroadcastServiceImpl.class);
    @Autowired
    private XydBroadcastConfig  xydBroadcastConfig;
    @Autowired
    private ApiBroadcastService apiBroadcastService;
    Map<String, String> areaCodeMap = NaXiAreaCode.getAreaCodeMap();
    /***
     * webMap缓存存储
     */
    public  static ConcurrentHashMap<String, Broadcast> broadcastHashMap = new ConcurrentHashMap<>();

    static {
        try {
            if (Files.exists(Paths.get(XydBroadcastConfig.START_BROADCAST_FILE_PATH))) {
                FileInputStream fileInputStream = new FileInputStream(XydBroadcastConfig.START_BROADCAST_FILE_PATH);
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
                broadcastHashMap = (ConcurrentHashMap<String, Broadcast>) objectInputStream.readObject();
                objectInputStream.close();
                fileInputStream.close();
                logger.info("读取广播记录文件成功");
            }
        }catch (Exception e){
            logger.error("读取广播记录文件失败",e);
        }
    }
    private static int errorCount = 0;

    //每30秒检测一次心跳
    /**
     * 定时循环检测心跳，检测到异常则关闭所有正在播放的广播
     * @return
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void checkHeartbeat() {
        //检测心跳,5次失败则关闭所有正在播放的广播


            String s = heartbeat();
//        logger.info("heartbeat:{}",s);

        if(broadcastHashMap != null && !broadcastHashMap.isEmpty() && errorCount>5){
            //关闭所有正在播放的广播
            closeBroadcastAll();
        }
        JSONObject json = JSONObject.parseObject(s);
        if(json != null && json.getBoolean("success")){
            errorCount = 0;
        }else{
            errorCount++;
//            logger.info("errorCount:{}",errorCount);
        }


        if (broadcastHashMap != null && !broadcastHashMap.isEmpty()) {
            //获取正在播放的广播，判断是否有正在播放的广播
//            List<Broadcast> xydPayingBroadcastList = getXydPayingBroadcastList();
//            if (xydPayingBroadcastList != null && !xydPayingBroadcastList.isEmpty()) {
//                isEbdPlaying = true;
//            } else {
//                isEbdPlaying = false;
//            }
//            //如果应急广播没有正在播放的广播，并且本地平台有正在播放的广播，则关闭所有正在播放的广播
//            if (!isEbdPlaying && isLocalPlaying) {
                //根据缓存的广播记录，查应急广播端的播放状态，没有播放关闭正在播放的广播

                getPlayingBroadcast();
//            }
        }
    }


    @Override
    public String heartbeat() {

        try {
            return   HttpClientUtil.doGet(xydBroadcastConfig.getUrl()+xydBroadcastConfig.getHeartbeatUrl(), null, null, null);

        } catch (Exception e) {
            errorCount ++;
            logger.info("errorCount:{}",errorCount);
        }
        return null;
    }

    /**
     *  开播
     * @param broadcast
     * @return
     */
    @Override
    public String startBroadcast(Broadcast broadcast) {

        String areaListString = convertAreaList(broadcast.getTargets());
        if(areaListString == null || areaListString.isEmpty()){
            logger.info("没有指定区域{}，无法开播", Arrays.toString(broadcast.getTargets()));
            return  "没有指定区域匹配区域，无法开播";
        }
        //查找callRecordId
        String startBroadcastCallRecordId = apiBroadcastService.findPlayingBroadcastCallRecordId(areaListString);
        //先判断是否有正在播放的区域广播
        if(startBroadcastCallRecordId != null && !startBroadcastCallRecordId.isEmpty()){
            logger.info("有正在播放的广播");
            broadcast.setCallRecordId(startBroadcastCallRecordId);
        }else {
            logger.info("没有正在播放的广播");
            IssueLiveStreamParamDTO issueLiveStreamParamDTO = new IssueLiveStreamParamDTO();
            issueLiveStreamParamDTO.setBroadCastType("1");//应急广播
            issueLiveStreamParamDTO.setEventLevel("0");

            issueLiveStreamParamDTO.setAreaListString(areaListString);
            IssueLiveStreamDTO issueLiveStreamDTO = apiBroadcastService.issueLiveStream(issueLiveStreamParamDTO);
            if(issueLiveStreamDTO != null ){
                if(issueLiveStreamDTO.getCallRecordId() != null && !issueLiveStreamDTO.getCallRecordId().isEmpty()){
                    //保存callRecordId
                    broadcast.setCallRecordId(issueLiveStreamDTO.getCallRecordId());
                }else {
                    logger.info("开播CallRecordId为空");
                    //没有返回，再根据区域查找callRecordId
                    String nowStartBroadcastCallRecordId = apiBroadcastService.findPlayingBroadcastCallRecordId(areaListString);
                    broadcast.setCallRecordId(nowStartBroadcastCallRecordId);
                }
            }
        }

        try {
            // 保存广播记录
            saveStartBroadcast(broadcast.getId(), broadcast);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return "";
    }
    @Override
    public String closeBroadcast(Broadcast broadcast) {
        //判断缓存是否有开播记录
        if(broadcastHashMap == null || broadcastHashMap.isEmpty()){
            return closeBroadcastAll();
        }
        Broadcast localBroadcast = broadcastHashMap.get(broadcast.getId());
        if(localBroadcast == null){
            return "";
        }
        String callRecordId = localBroadcast.getCallRecordId();
        if(callRecordId == null || callRecordId.isEmpty()){
            logger.info("没有callRecordId");
            //补偿措施，根据播放区域区域，查询callRecordId
            String areaListString = convertAreaList(broadcast.getTargets());
            if(areaListString == null || areaListString.isEmpty()){
                logger.info("没有指定区域{}，无法关播", Arrays.toString(broadcast.getTargets()));
                return  "没有指定区域匹配区域，无法关播";
            }

            callRecordId = apiBroadcastService.findPlayingBroadcastCallRecordId(areaListString);
            if(callRecordId == null || callRecordId.isEmpty()){

                closeBroadcastMap(broadcast);
                return  "没有callRecordId";
            }
            localBroadcast.setCallRecordId(callRecordId);
        }


            logger.info("有正在播放的广播，关播");
            apiBroadcastService.stopIssueAudioFile(callRecordId);

//            logger.info("没有正在播放的广播，关播");
//            String startBroadcastCallRecordId = apiBroadcastService.findStartBroadcastCallRecordId();
//            if(startBroadcastCallRecordId != null && !startBroadcastCallRecordId.isEmpty()){
//                apiBroadcastService.stopIssueAudioFile(startBroadcastCallRecordId);
//            }
        closeBroadcastMap(broadcast);
        return "";
    }

    /**
     *  关播所有
     * @return
     */
    public String closeBroadcastAll() {
        return apiBroadcastService.closeBroadcastAll();
    }

    // 	应急广播平台区域  510503 四川 泸州市 纳溪区   510503001 安富街道	510503001001上坝街居民委员会
// 	纳溪本地区划  5105030000  纳溪区     5105030100  安富街道    5105030101 四川 泸州市 纳溪区 安富街道 上坝社区居民委员会
    public String convertAreaList(String[] areaList) {
//return  "5105030101";

        if (areaList == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (String area : areaList) {
            if (area == null || area.isEmpty()) {
                continue;
            }
            //过滤设备
            if (area.length() > 12) {
                continue;
            }
            String convertedArea = convertNaXiAreaCode(area);
            if (convertedArea == null || convertedArea.isEmpty()) {
                continue;
            }
            sb.append(convertedArea).append(",");
        }
        if (sb.length() == 0) {
            return null;
        }
        return sb.toString().substring(0, sb.length() - 1);
    }

    private String convertNaXiAreaCode(String area) {
        return areaCodeMap.get(area);
    }



    /**
     *  获取正在播放的广播列表
     * @return
     */
    @Override
    public List<Broadcast> getXydPayingBroadcastList() {
        // 查所有在播广播
        String s = null;
        try {
            s = HttpClientUtil.doGet(xydBroadcastConfig.getUrl() + xydBroadcastConfig.getBroadcastListUrl(), null, null, null);
            logger.info("获取应急广播平台广播列表结果：{}", s);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        JSONObject json = JSONObject.parseObject(s);
        List<Broadcast> broadcasts = json.getJSONArray("broadcastList").toJavaList(Broadcast.class);
        return broadcasts;
    }

    /**
     * 获取应急广播平台的广播
     * @param broadcastId
     * @return
     */
    @Override
    public Broadcast getXydBroadcast(String broadcastId) {

        if(broadcastId != null && !broadcastId.isEmpty()){

            try {
                Map<String, String> params = new HashMap<>();
                params.put("broadcastId", broadcastId);
                String s = HttpClientUtil.doGet(xydBroadcastConfig.getUrl() + xydBroadcastConfig.getBroadcastListUrl(), params, null, null);
                logger.info("获取应急广播平台广播结果：{}", s);
                JSONObject json = JSONObject.parseObject(s);
                if(json != null && json.getBoolean("success")){
                    List<Broadcast> broadcasts = json.getJSONArray("broadcastList").toJavaList(Broadcast.class);

                    if(broadcasts == null || broadcasts.isEmpty()){
                        return null;
                    }
                    return broadcasts.get(0);
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    /**
     *  关闭广播，删除内存中的广播，并保存到文件
     * @param broadcast
     */
    private static void closeBroadcastMap(Broadcast broadcast) {

        broadcast =    getLocalBroadcast(broadcast.getId());
        if(broadcast == null){
            return;
        }
        try {
            broadcastHashMap.remove(broadcast.getId());
            try (ObjectOutputStream oos = new ObjectOutputStream(
                    Files.newOutputStream(Paths.get(XydBroadcastConfig.START_BROADCAST_FILE_PATH)))) {
                oos.writeObject(broadcastHashMap);
                System.out.println("关播Broadcast已更新保存到: " + XydBroadcastConfig.START_BROADCAST_FILE_PATH);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // 保存Broadcast到内存和文件
    private static void saveStartBroadcast(String broadcastId, Broadcast broadcast) throws IOException {


       broadcastHashMap.put(broadcastId,broadcast);

        try (ObjectOutputStream oos = new ObjectOutputStream(
                Files.newOutputStream(Paths.get(XydBroadcastConfig.START_BROADCAST_FILE_PATH)))) {
            oos.writeObject(broadcastHashMap);
            System.out.println("开播Broadcast已保存到: " + XydBroadcastConfig.START_BROADCAST_FILE_PATH);
        }
    }

    // 从文件加载Broadcast
    public static Broadcast getLocalBroadcast(String broadcastId) {

        if(broadcastHashMap.containsKey(broadcastId)){
            Broadcast broadcast = broadcastHashMap.get(broadcastId);
            if(broadcast != null ){
                return broadcast;
            } else {
               return null;
            }
        } else {
            ConcurrentHashMap<String, Broadcast> broadcastConcurrentHashMap = getBroadcastHashMap();
            if(!broadcastConcurrentHashMap.isEmpty()){
                return broadcastConcurrentHashMap.get(broadcastId);
            } else {
                return null;
            }
        }
    }

    private static ConcurrentHashMap<String, Broadcast> getBroadcastHashMap() {

        if(broadcastHashMap.isEmpty()){
            try {
                broadcastHashMap = (ConcurrentHashMap<String, Broadcast>) new ObjectInputStream(
                        new FileInputStream(XydBroadcastConfig.START_BROADCAST_FILE_PATH)).readObject();
                logger.info("从文件加载了 {} 个broadcast", broadcastHashMap.size());
            } catch (Exception e) {
                logger.error("error:{},{}","startBroadcastRecords.br (系统找不到指定的文件。)"+ e.getMessage(),"无播放广播记录");
            }
        }
        return broadcastHashMap;
    }

    /**
     * 获取正在播放的广播，获取map中广播状态
     * @return
     */
    public void getPlayingBroadcast() {
        ConcurrentHashMap<String, Broadcast> broadcastHashMap1 = getBroadcastHashMap();
        for (Map.Entry<String, Broadcast> entry : broadcastHashMap1.entrySet()) {
            Broadcast broadcast = entry.getValue();
            Broadcast xydBroadcast = getXydBroadcast(broadcast.getId());
            // 判断xydBroadcast状态 是否为播放中 未播放则关闭
            if(xydBroadcast != null && xydBroadcast.getStatus() != null && xydBroadcast.getStatus() != Broadcast.Status.PLAYING){
               closeBroadcast( broadcast);
            }else if(xydBroadcast == null){ // 广播平台未存在广播，删除内存中的广播
                closeBroadcast( broadcast);
            }

        }
    }
}
